---
title: 'proxy'
section: 'API'
subSection: 'Basic'
description: 'Create a proxy object.'
---

# `proxy`

The `proxy` tracks changes to the original object and all nested objects, notifying listeners when an object is modified.

```js
import { proxy } from 'valtio'

const state = proxy({ count: 0, text: 'hello' })
```

## Mutate from anywhere

You can make changes to it in the same way you would to a normal js-object.

```js
setInterval(() => {
  ++state.count
}, 1000)
```

## Optimizations: noop and batching

Updates that set the value of a property to the same value are ignored. Subscribers will not be informed of a version change.

```js
const state = proxy({ count: 0 })

state.count = 0 // has no effect
```

Multiple changes in the same event loop tick will be batched together. Subscribers will be notified of a single version change.

```js
const state = proxy({ count: 0, text: 'hello' })
// subscribers will be notified once after both mutations
state.count = 1
state.text = 'world'
```

## Nested proxies

Proxies can be nested in other `proxy` objects and updated as a whole.

```jsx
import { proxy, useSnapshot } from 'valtio'

const personState = proxy({ name: 'Timo', role: 'admin' })
const authState = proxy({ status: 'loggedIn', user: personState })

authState.user.name = 'Nina'
```

## Promises in proxies

See [`async`](../../guides/async) for more details.

```jsx
import { proxy } from 'valtio'

const bombState = proxy({
  explosion: new Promise((resolve) => setTimeout(() => resolve('Boom!'), 3000)),
})
```

## Gotchas

If you reassign the proxy to an entirely new object, it will stop working because you are replacing the proxied object with a new object reference.

```jsx
let state = proxy({ user: { name: 'Timo' } })

subscribe(state, () => {
  console.log(state.user.name)
})
// will not notify subscribers
state = { user: { name: 'Nina' } }

// instead
let state = proxy({ user: { name: 'Timo' } })

subscribe(state, () => {
  console.log(state.user.name) // logs "Nina"
})
// will notify subscribers
state.user.name = 'Nina'
```

Not everything can be proxied. Generally, you are safe if it is serializable. Classes can also be proxied. But avoid special objects.

```jsx
// these won't work - changes to these objects won't cause updates
// to store state that is unproxied see the docs on ref
const state = proxy({
  chart: d3.select('#chart'),
  component: React.createElement('div'),
  map: new Map(), // see proxyMap
  storage: localStorage,
})

// this will work
class User {
  first = null
  last = null
  constructor(first, last) {
    this.first = first
    this.last = last
  }
  greet() {
    return `Hi ${this.first}!`
  }
  get fullName() {
    return `${this.first} ${this.last}`
  }
}
const state = proxy(new User('Timo', 'Kivinen'))
```
